package bank.model.vo;

import java.sql.ResultSet;
import java.util.ArrayList;


/**
 * 
 * @author Andrei Glazunov
 *
 */
public class Department
{
	protected int id;
	private String name;
	protected ArrayList<Department> subdepts;
	protected Department parent; 
	
	protected Department() {
		subdepts = new ArrayList<Department>(); 
	}
	
	protected Department(String name) {
		this();
		this.name = name;
	}
	
	private Department(int id, String name)	{
		this(name);
		this.id = id;		
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * This method is used when loading department structure from database
	 * @param dept
	 */
	public void addExistingSubdept(Department dept) {	
		subdepts.add(dept);
		dept.parent = this;
	}	

	public String getName() {
		return name;		
	}
	
	public int getId() {
		return id;		
	}
	
	public Department getParent() {
		return parent;		
	}
	
	public int getSubdeptsNum()	{
		return subdepts.size();		
	}	
	
	/**
	 * Retrieves all subdepartments
	 * @return
	 */
	public ArrayList<Department> getSubdepts()	{		
		return subdepts;		
	}
	
	public ArrayList<Employee> getEmployees(Bank b)	{
		ArrayList<Employee> staff = new ArrayList<Employee>();
		for (Employee e: b.staff) {
			staff.add(e);
		}		
		return staff;		
	}	

	public String toString() {
		return name + "(id: "+ String.valueOf(id)+")";		
	}
	
	/**
	 * Resursive procedure used in print() method
	 * @param off
	 * @param d
	 */
	private void output(String off, Department d) {
		System.out.println(off + d);
		for (Department s: d.subdepts) {
			output(off + '\t', s);
		}
	}
	
	/**
	 * Prints department tree starting with current one  
	 *
	 */
	public void print() {
		output("", this);
	}
	
	/**
	 * Searches for department in loaded structure
	 * @param id
	 * @param d Department object, used for recursive processing  
	 * @return Department object 
	 */
	protected Department findDept(int id, Department d) {
		for (Department s: d.subdepts) {
			if (s.getId() == id)
				return s;
			Department buf = findDept(id, s); 
			if (buf != null)
				return buf;
		}		
		return null;
	}
	
	/**
	 * Forms SQL query for department insertion
	 * @param parentid
	 * @return SQL expression
	 */
	protected String insertionSQL(int parentid) {
		if (parentid != 0)
			return "INSERT INTO DEPARTMENTS (NAME, PARENT_ID) " +
			"VALUES ('" +name+ "', '" +parentid+ "')";
		else
			return "INSERT INTO DEPARTMENTS (NAME, PARENT_ID) " +
			"VALUES ('" +name+ "', NULL)";
	}
	
	/**
	 * Recursive function that fetches children of specified department 
	 * and adds them to department structure
	 * @param rs ResultSet from SELECT query
	 * @param parentid
	 * @throws Exception
	 */
	protected void processResultSet(ResultSet rs, int parentid) throws Exception {
		int row = 0;
		rs.beforeFirst();		
		while (rs.next()) {			
			if (rs.getInt("PARENT_ID") == parentid) {
				Department dept = new Department(rs.getInt("ID"), rs.getString("NAME"));				
				addExistingSubdept(dept);
				row = rs.getRow();				
				dept.processResultSet(rs, dept.id);
				rs.absolute(row);				
			}				
		}
	}
}
